using System;
using System.Collections.Generic;
using UnityEngine;

namespace GenerativeAgents.Core
{
    /// <summary>
    /// 空间记忆节点
    /// 表示环境中的一个空间区域，支持层次化的空间结构
    /// </summary>
    [System.Serializable]
    public class SpatialNode
    {
        [Header("基础空间信息")]
        public string name;                 // 空间名称
        public string description;          // 空间描述
        public Vector3 position;            // 中心位置
        public Vector3 bounds;              // 边界大小
        public Quaternion rotation;         // 旋转
        
        [Header("层次结构")]
        public SpatialNode parent;          // 父节点
        public Dictionary<string, SpatialNode> children; // 子节点
        public int depth;                   // 层次深度
        
        [Header("空间内容")]
        public List<string> objects;        // 空间内的对象
        public List<string> agents;         // 空间内的智能体
        public List<string> features;       // 空间特征
        
        [Header("导航信息")]
        public List<Vector3> waypoints;     // 路径点
        public List<SpatialConnection> connections; // 连接到其他空间
        public bool isAccessible;           // 是否可达
        public float movementCost;          // 移动成本
        
        [Header("空间属性")]
        public SpatialType spatialType;     // 空间类型
        public Dictionary<string, object> properties; // 属性字典
        public DateTime lastUpdated;        // 最后更新时间
        
        [Header("语义信息")]
        public List<string> tags;           // 标签
        public float[] embedding;           // 空间的语义嵌入
        
        public SpatialNode()
        {
            children = new Dictionary<string, SpatialNode>();
            objects = new List<string>();
            agents = new List<string>();
            features = new List<string>();
            waypoints = new List<Vector3>();
            connections = new List<SpatialConnection>();
            properties = new Dictionary<string, object>();
            tags = new List<string>();
            lastUpdated = DateTime.Now;
            isAccessible = true;
            movementCost = 1f;
        }
        
        /// <summary>
        /// 创建世界根节点
        /// </summary>
        public static SpatialNode CreateWorld(string worldName)
        {
            return new SpatialNode
            {
                name = worldName,
                description = $"The world of {worldName}",
                spatialType = SpatialType.World,
                depth = 0,
                bounds = new Vector3(1000, 100, 1000) // 默认世界大小
            };
        }
        
        /// <summary>
        /// 添加子空间
        /// </summary>
        public SpatialNode AddChild(string childName, Vector3 relativePosition, Vector3 childBounds, SpatialType childType = SpatialType.Room)
        {
            var child = new SpatialNode
            {
                name = childName,
                description = $"{childType} named {childName}",
                position = position + relativePosition,
                bounds = childBounds,
                parent = this,
                depth = depth + 1,
                spatialType = childType
            };
            
            children[childName] = child;
            return child;
        }
        
        /// <summary>
        /// 移除子空间
        /// </summary>
        public bool RemoveChild(string childName)
        {
            if (children.TryGetValue(childName, out var child))
            {
                child.parent = null;
                children.Remove(childName);
                return true;
            }
            return false;
        }
        
        /// <summary>
        /// 查找子空间（递归）
        /// </summary>
        public SpatialNode FindChild(string childName, bool recursive = true)
        {
            if (children.TryGetValue(childName, out var directChild))
            {
                return directChild;
            }
            
            if (recursive)
            {
                foreach (var child in children.Values)
                {
                    var found = child.FindChild(childName, true);
                    if (found != null) return found;
                }
            }
            
            return null;
        }
        
        /// <summary>
        /// 添加对象到空间
        /// </summary>
        public void AddObject(string objectName)
        {
            if (!objects.Contains(objectName))
            {
                objects.Add(objectName);
                lastUpdated = DateTime.Now;
            }
        }
        
        /// <summary>
        /// 移除空间中的对象
        /// </summary>
        public bool RemoveObject(string objectName)
        {
            var removed = objects.Remove(objectName);
            if (removed)
            {
                lastUpdated = DateTime.Now;
            }
            return removed;
        }
        
        /// <summary>
        /// 添加智能体到空间
        /// </summary>
        public void AddAgent(string agentName)
        {
            if (!agents.Contains(agentName))
            {
                agents.Add(agentName);
                lastUpdated = DateTime.Now;
            }
        }
        
        /// <summary>
        /// 移除空间中的智能体
        /// </summary>
        public bool RemoveAgent(string agentName)
        {
            var removed = agents.Remove(agentName);
            if (removed)
            {
                lastUpdated = DateTime.Now;
            }
            return removed;
        }
        
        /// <summary>
        /// 检查位置是否在此空间内
        /// </summary>
        public bool ContainsPosition(Vector3 worldPosition)
        {
            var localPos = worldPosition - position;
            return Mathf.Abs(localPos.x) <= bounds.x / 2 &&
                   Mathf.Abs(localPos.y) <= bounds.y / 2 &&
                   Mathf.Abs(localPos.z) <= bounds.z / 2;
        }
        
        /// <summary>
        /// 获取到目标位置的距离
        /// </summary>
        public float GetDistanceTo(Vector3 targetPosition)
        {
            return Vector3.Distance(position, targetPosition);
        }
        
        /// <summary>
        /// 获取到另一个空间的距离
        /// </summary>
        public float GetDistanceTo(SpatialNode otherNode)
        {
            return Vector3.Distance(position, otherNode.position);
        }
        
        /// <summary>
        /// 添加空间连接
        /// </summary>
        public void AddConnection(SpatialNode target, float cost = 1f, string connectionType = "default")
        {
            var connection = new SpatialConnection
            {
                target = target,
                cost = cost,
                connectionType = connectionType,
                isActive = true
            };
            connections.Add(connection);
        }
        
        /// <summary>
        /// 获取所有可达的邻接空间
        /// </summary>
        public List<SpatialNode> GetAccessibleNeighbors()
        {
            var neighbors = new List<SpatialNode>();
            foreach (var connection in connections)
            {
                if (connection.isActive && connection.target.isAccessible)
                {
                    neighbors.Add(connection.target);
                }
            }
            return neighbors;
        }
        
        /// <summary>
        /// 获取空间的完整路径名称
        /// </summary>
        public string GetFullPath()
        {
            if (parent == null) return name;
            return parent.GetFullPath() + "/" + name;
        }
        
        /// <summary>
        /// 更新空间信息
        /// </summary>
        public void UpdateSpatialInfo(List<string> newObjects = null, List<string> newAgents = null, List<string> newFeatures = null)
        {
            if (newObjects != null)
            {
                objects.Clear();
                objects.AddRange(newObjects);
            }
            
            if (newAgents != null)
            {
                agents.Clear();
                agents.AddRange(newAgents);
            }
            
            if (newFeatures != null)
            {
                features.Clear();
                features.AddRange(newFeatures);
            }
            
            lastUpdated = DateTime.Now;
        }
        
        /// <summary>
        /// 获取空间的文本描述
        /// </summary>
        public string GetTextDescription()
        {
            var desc = $"{name} is a {spatialType}";
            
            if (objects.Count > 0)
            {
                desc += $" containing {string.Join(", ", objects)}";
            }
            
            if (agents.Count > 0)
            {
                desc += $" with {string.Join(", ", agents)} present";
            }
            
            if (features.Count > 0)
            {
                desc += $" featuring {string.Join(", ", features)}";
            }
            
            return desc;
        }
    }
    
    /// <summary>
    /// 空间连接
    /// </summary>
    [System.Serializable]
    public class SpatialConnection
    {
        public SpatialNode target;          // 目标空间
        public float cost;                  // 移动成本
        public string connectionType;       // 连接类型（门、楼梯、通道等）
        public bool isActive;               // 是否激活
        public Vector3 entryPoint;          // 进入点
        public Vector3 exitPoint;           // 退出点
        public Dictionary<string, object> properties; // 连接属性
        
        public SpatialConnection()
        {
            cost = 1f;
            connectionType = "default";
            isActive = true;
            properties = new Dictionary<string, object>();
        }
    }
    
    /// <summary>
    /// 空间类型
    /// </summary>
    public enum SpatialType
    {
        World,          // 世界
        Region,         // 区域
        Building,       // 建筑
        Floor,          // 楼层
        Room,           // 房间
        Area,           // 区域
        Furniture,      // 家具
        Object          // 对象
    }
}